<script setup lang="ts">
import type { DescriptionItemSchema, EnhancedDescriptionProps } from './types';

import { computed } from 'vue';

import {
  ElCard,
  ElDescriptions,
  ElDescriptionsItem,
  ElSkeleton,
} from 'element-plus';
// 定义 props 的默认值
const props = withDefaults(defineProps<EnhancedDescriptionProps>(), {
  column: () => 2,
  border: () => true,
  direction: () => 'horizontal' as const,
  size: () => 'default' as const,
  card: () => false,
  loading: () => false,
  emptyText: () => '-',
});

// 定义 emits
const emit = defineEmits<{
  itemClick: [item: DescriptionItemSchema, data: any];
}>();

// 计算可见的 schema 项
const visibleSchema = computed(() => {
  return props.schema.filter((item) => {
    if (typeof item.hidden === 'function') {
      return !item.hidden(props.data);
    }
    return !item.hidden;
  });
});

// 获取项的唯一 key
const getItemKey = (item: DescriptionItemSchema): string => {
  return item.field || item.label;
};

// 获取插槽名称
const getSlotName = (item: DescriptionItemSchema): string => {
  return item.field || item.label;
};

// 获取内容
const getContent = (item: DescriptionItemSchema): string => {
  try {
    // 优先使用 content 函数
    if (item.content) {
      const content = item.content(props.data);
      return content ?? props.emptyText;
    }

    // 其次使用 formatter
    if (item.formatter && item.field) {
      const value = props.data[item.field];
      return item.formatter(value, props.data) ?? props.emptyText;
    }

    // 最后使用 field 直接取值
    if (item.field) {
      const value = props.data[item.field];
      return value ?? props.emptyText;
    }

    return props.emptyText;
  } catch (error) {
    console.error(`Error rendering content for ${item.label}:`, error);
    return props.emptyText;
  }
};

// 项点击事件
const handleItemClick = (item: DescriptionItemSchema) => {
  emit('itemClick', item, props.data);
};
</script>

<template>
  <!-- 卡片模式 -->
  <ElCard
    v-if="props.card"
    :header="props.cardTitle"
    shadow="never"
    :class="props.cardClass"
  >
    <template #header v-if="$slots.header">
      <slot name="header" :data="props.data" :schema="props.schema"></slot>
    </template>

    <ElSkeleton :loading="props.loading" animated :rows="10">
      <template #default>
        <ElDescriptions
          :column="props.column"
          :border="props.border"
          :direction="props.direction"
          :size="props.size"
        >
          <template v-for="item in visibleSchema" :key="getItemKey(item)">
            <ElDescriptionsItem
              :label="item.label"
              :span="item.span"
              :label-class="item.labelClass"
              :class="item.contentClass"
            >
              <slot
                v-if="$slots[getSlotName(item)]"
                :name="getSlotName(item)"
                :data="props.data"
                :item="item"
              ></slot>
              <template v-else>
                <span v-html="getContent(item)"></span>
              </template>
            </ElDescriptionsItem>
          </template>
        </ElDescriptions>
      </template>
    </ElSkeleton>
  </ElCard>

  <!-- 非卡片模式 -->
  <ElSkeleton v-else :loading="props.loading" animated :rows="10">
    <template #default>
      <ElDescriptions
        :title="props.title"
        :column="props.column"
        :border="props.border"
        :direction="props.direction"
        :size="props.size"
        :extra="props.extra"
      >
        <template #title v-if="$slots.title">
          <slot name="title" :data="props.data" :schema="props.schema"></slot>
        </template>

        <template #extra v-if="$slots.extra">
          <slot name="extra" :data="props.data" :schema="props.schema"></slot>
        </template>

        <template v-for="item in visibleSchema" :key="getItemKey(item)">
          <ElDescriptionsItem
            :label="item.label"
            :span="item.span"
            :label-class="item.labelClass"
            :class="item.contentClass"
            min-width="100"
          >
            <slot
              v-if="$slots[getSlotName(item)]"
              :name="getSlotName(item)"
              :data="props.data"
              :item="item"
            ></slot>
            <template v-else>
              <span>{{ getContent(item) }}</span>
            </template>
          </ElDescriptionsItem>
        </template>
      </ElDescriptions>
    </template>
  </ElSkeleton>
</template>

<style scoped>
:deep(.ElDescriptions__body) {
  background-color: transparent;
}

:deep(.ElDescriptions__label) {
  font-weight: 500;
}

/* 自定义样式类 */
.label-bold :deep(.ElDescriptions__label) {
  font-weight: 600;
}

.label-large :deep(.ElDescriptions__label) {
  font-size: 14px;
}

.content-highlight :deep(.ElDescriptions__content) {
  font-weight: 500;
  color: #409eff;
}
</style>
